package com.byComputer.bo;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import com.byComputer.util.CookieUtils;
import com.byComputer.vo.Computer;

/**
 * @购物车：包含了很多的购物票
 * @author WangPeihu
 * 
 */
public class Cart {

	/** 一个cart包含了若干了购买了的东西小票 */
	private Map<Integer, CartItem> items = new HashMap<Integer, CartItem>();
	private ComputerService computerService = new ComputerService();

	/**
	 * 用了工厂模式，对象创建的过程比较复杂的时候，用了工厂模式。
	 * 每次调用这个方法的时候就创建了一个Cart对象，不用new了
	 * 
	 * @return
	 */
	public static Cart getInstance(HttpServletRequest request) {

		/** 获的dession对象 */
		HttpSession session = request.getSession();
		Cart cart = (Cart) session.getAttribute("cart_key");
		System.out.println("不是第一次点击这个按钮了");
		if (cart == null) {
			System.out.println("说明是第一次点这个按钮");
			cart = new Cart();
			session.setAttribute("cart_key", cart);
		}
		return cart;
	}

	/*
	 * @getInstanceByCookie
	 * @param request
	 * @return
	 *
	public static Cart getInstanceByCookie(HttpServletRequest request,
			HttpServletResponse response) {
		Cart cart = new Cart();
		String cartStr = CookieUtils.findCookie("cart_key",request);
		/** 如果是第一次调用会将对象序列化 
		if (cookie != null) {
			for (Cookie cookie1 : cookie) {
				if ("cart_key".equals(cookie1.getName())) {
					cartStr = cart.serialie(cookie1);
					Cookie cook = new Cookie("cart_key", cartStr);
					cook.setPath("byComputer");
					response.addCookie(cook);
				}
			}
		}
		for (Cookie cookie2 : cookie) {
			cartStr = cookie2.getValue();
			cart.reSerialie(cartStr);
		}
		return cart;
	}
*/
	/**
	 * @addItem
	 * @param computerId
	 * @return
	 */
	public boolean addItem(Integer computerId) {
		/** 判断computerId这个键值<key> 是否存在于items这个map集合中 */
		if (!items.containsKey(computerId)) {
			Computer computer = computerService.getComputer(computerId);
			CartItem item = new CartItem();
			item.setComputer(computer);
			item.setNumber(1);
			items.put(computer.getId(), item);
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @compute total price
	 * @return
	 */
	public BigDecimal getTotalPrice() {
		BigDecimal totalPrice = new BigDecimal("0");
		for (Integer id : items.keySet()) {
			CartItem cartItem = items.get(id);
			totalPrice = totalPrice.add(cartItem.getComputer().getPrice()
					.multiply(BigDecimal.valueOf(cartItem.getNumber())));
		}
		return totalPrice;
	}

	/**
	 * @delete a Item
	 * @param computerId
	 * @return
	 */
	public boolean removeItem(Integer computerId) {
		if (items.containsKey(computerId)) {
			items.remove(computerId);
			System.out.println("要删除的Item的确存在于这里");
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @Update Item
	 * @param computerId
	 * @param newNumber
	 * @return
	 */
	public boolean updateItem(int computerId, int newNumber) {
		if (items.containsKey(computerId)) {
			CartItem item = items.get(computerId);
			item.setNumber(newNumber); // 可变对象，不要从新put
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @clear items
	 */
	public void clear() {
		items.clear();
	}

	/**
	 * @GetItems
	 * @return List<CartItem>
	 */
	public List<CartItem> getItems() {
		List<CartItem> itemList = new ArrayList<CartItem>();
		for (Integer id : items.keySet()) {
			itemList.add(items.get(id));
		}
		return itemList;
	}

	/**
	 * 实现兑现序列化
	 * 
	 * @return
	 */
	public String serialie(Object obj) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(items);
			byte[] bs = baos.toByteArray();
			oos.close();
			BASE64Encoder encoder = new BASE64Encoder();
			return encoder.encode(bs);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 反序列华,将反序列化的东西赋值给items
	 * 
	 */
	public void reSerialie(String cartStr) {
		try {
			BASE64Decoder decoder = new BASE64Decoder();
			byte[] bs1 = decoder.decodeBuffer(cartStr);
			ObjectInputStream ois = new ObjectInputStream(
					new ByteArrayInputStream(bs1));
			Map map = (Map) ois.readObject();
			items = map;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	public void setItems(Map<Integer, CartItem> items) {
		this.items = items;
	}
}
